package irc
import (
	"bytes"
	"io"
	"errors"
)

func Read_uint8(r io.Reader) (uint8,error) {

	var b [1]byte
	if _, err := io.ReadFull(r, b[:]); err != nil {
       return  0,err
	}
	return b[0],nil
}
func Read_uint16(r io.Reader) (uint16,error) {
	var b [2]byte
	if _, err := io.ReadFull(r, b[:]); err != nil {
      return  0,err
	}
	return uint16(b[0])<<8 | uint16(b[1]),nil
}
func Read_String(r io.Reader) (string,error) {
	strLen,err := Read_uint16(r)
	if err !=nil {
		return "",err
	}
	b := make([]byte, strLen)
	if _, err := io.ReadFull(r, b); err != nil {
		return  "",errors.New( "Byte length is not enough")
	}
	return string(b),nil
}
func Write_uint8(val uint8,   buf *bytes.Buffer) {
	buf.WriteByte(byte(val))
}
func Write_uint16(val uint16, buf *bytes.Buffer) {
	buf.WriteByte(byte(val & 0xff00 >> 8))
	buf.WriteByte(byte(val & 0x00ff))
}
func Write_String(val string, buf *bytes.Buffer) {
	length := uint16(len(val))
	Write_uint16(length, buf)
	buf.WriteString(val)
}
func BoolToByte(val bool) byte {
	if val {
		return byte(1)
	}
	return byte(0)
}
func DecodeLength(r io.Reader) (int32,error) {
	var v int32
	var buf [1]byte
	var shift uint
	for i := 0; i < 4; i++ {
		if _, err := io.ReadFull(r, buf[:]); err != nil {
			return  0,err
		}
		b := buf[0]
		v |= int32(b&0x7f) << shift
		if b&0x80 == 0 {
			return v,nil
		}
		shift += 7
	}
	return  v,nil
}
func EncodeLength(length int32, buf *bytes.Buffer) {
	if length == 0 {
		buf.WriteByte(0)
		return
	}
	for length > 0 {
		digit := length & 0x7f
		length = length >> 7
		if length > 0 {
			digit = digit | 0x80
		}
		buf.WriteByte(byte(digit))
	}
}